﻿using NCP.Core;
using NCP.Core.DataUtil;
using NCP.Core.Exceptions;
using NCP.Core.Extensions;
using NCP.Core.IoC;
using NCP.Model;
using NCP.Util;
using Newtonsoft.Json;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Data;

namespace NCP.Service
{
    public class LimitDrugService : IService
    {
        private SqlSugarClient _client;
        public LimitDrugService()
        {
            _client = DbHelper.GetSqlSugarClient();
        }

        public object GetLimitDrugList(Expressionable<PhaBaseInfo> exp, PageModel page, string orderFields = "DrugName")
        {
            int count = 0;
            var memberService = new MemberService();
            var result = _client.Queryable<PhaBaseInfo>()
                .Where(exp.ToExpression())
                .OrderBy(orderFields)
                .ToPageList(page.PageIndex, page.PageSize, ref count);
            page.TotalCount = count;
            return result;
        }


        public object GetLimitInfoList(Expressionable<LimitDrug> exp, PageModel page, string orderFields = "Code")
        {
            int count = 0;
            var memberService = new MemberService();
            var result = _client.Queryable<LimitDrug>()
                .Where(exp.ToExpression())
                .Select(x => (dynamic)new
                {
                    x.Type,
                    x.Code,
                    x.DrugCode,
                    x.Status,
                    DrugName = SqlFunc.Subqueryable<PhaBaseInfo>().Where(b => b.DrugCode == x.DrugCode).Select(b => b.DrugName + "【" + b.Specs + "】"),
                    LimitName = SqlFunc.IF(x.Type == "1").Return(SqlFunc.Subqueryable<DeptInfo>().Where(sd => sd.DeptCode == x.Code).Select(sd => sd.DeptName))
                                       .ElseIF(x.Type == "2").Return(SqlFunc.Subqueryable<PatientInfo>().Where(sp => sp.InpatientNo == x.Code).Select(sp => sp.PatientName + "[" + sp.InpatientNo + "]"))
                                       .End("")
                })
                .Mapper(x =>
                {
                    x.Oper = memberService.GetMemberNameByCodeCache(x.OperCode) ?? x.OperCode;
                    if (x.Type == "1") x.TypeName = "科室";
                    else if (x.Type == "2") x.TypeName = "患者";
                    else x.TypeName = "";
                    if (x.Status == "1") x.StatusName = "限制";
                    else if (x.Status == "2") x.StatusName = "放开";
                    else x.StatusName = "";
                    x.ValidFlagName = x.ValidFlag == "1" ? "有效" : "无效";
                })
                .OrderBy(orderFields)
                .ToPageList(page.PageIndex, page.PageSize, ref count);
            page.TotalCount = count;
            return result;
        }

        public int SaveLimitDrug(List<LimitDrug> items, string drugCode, string type)
        {
            if (items == null) items = new List<LimitDrug>();

            #region 检查数据

            string checkmsg = "";
            foreach (var item in items)
            {
                if (string.IsNullOrEmpty(item.Code))
                {
                    checkmsg += $"【{item.Name}】项目编码为空!\r\n";
                }
                if (item.Status != "1" && item.Status != "2")
                {
                    checkmsg += $"【{item.Name}】未选择限制或放开!\r\n";
                }
            }
            MessageException.CheckException(checkmsg != "", checkmsg);

            #endregion

            Member oper = MemberUtil.GetCurrentMember();
            string operCode = oper?.Code;
            DateTime operDate = DateTime.Now;
            var oldItems = _client.Queryable<LimitDrug>().Where(x => x.DrugCode == drugCode && x.Type == type).ToList();

            _client.BeginTran();
            try
            {
                #region 操作日志

                string oldCon = "";
                string newCon = "";
                oldItems.ForEach(x => oldCon += $"{x.Code},{x.Status}^");
                items.ForEach(x => newCon += $"{x.Code},{x.Status}^");
                SysOperLogService.WriteSysOperLog(new SysOperLog
                {
                    EventType = "修改限制药品使用",
                    EventCon = $"修改药品编码:{drugCode},Type:{type}",
                    OldCon = oldCon.TrimEnd('^'),
                    NewCon = newCon.TrimEnd('^')
                });

                #endregion
                //删除信息
                List<string> delIds = new List<string>();
                foreach (var item in oldItems)
                {
                    if (!items.Exists(x => x.Code == item.Code))
                    {
                        delIds.Add(item.Code);
                    }
                }
                if (delIds.Count > 0)
                {
                    _client.Deleteable<LimitDrug>()
                        .Where(x => x.DrugCode == drugCode && x.Type == type && delIds.Contains(x.Code))
                        .ExecuteCommand();
                }
                //保存信息 
                var insertItems = new List<LimitDrug>();
                var updateItems = new List<LimitDrug>();
                foreach (var item in items)
                {
                    item.Type = type;
                    item.DrugCode = drugCode;
                    if (oldItems.Exists(x => x.Code == item.Code))
                    {
                        updateItems.Add(item);
                    }
                    else
                    {
                        insertItems.Add(item);
                    }
                }
                _client.Insertable(insertItems).ExecuteCommand();
                _client.Updateable(updateItems).WhereColumns(x => new { x.Type, x.DrugCode, x.Code }).ExecuteCommand();

                _client.CommitTran();
            }
            catch
            {
                _client.RollbackTran();
                throw;
            }
            return 1;
        }

        public PhaBaseInfo GetPhaBaseInfo(string drugCode)
        {
            return _client.Queryable<PhaBaseInfo>().Where(x => x.DrugCode == drugCode).First();
        }

        public object LimitDeptUnChose(string drugCode)
        {
            var data = _client.Queryable<DeptInfo>()
                .LeftJoin<LimitDrug>((di, ld) => ld.DrugCode == drugCode && ld.Type == "1" && ld.Code == di.DeptCode)
                .Where((di, ld) => di.ValidFlag == "1" && SqlFunc.EqualsNull(ld.DrugCode, null))
                .Select((di, ld) => (dynamic)new { Code = di.DeptCode, Name = di.DeptName, di.SpellCode, Status = "1" })//科室默认限制
                .ToArray();

            return data;
        }

        public object LimitDeptChose(string drugCode)
        {
            var data = _client.Queryable<DeptInfo>()
                .InnerJoin<LimitDrug>((di, ld) => ld.DrugCode == drugCode && ld.Type == "1" && ld.Code == di.DeptCode)
                .Where((di, ld) => di.ValidFlag == "1")
                .Select((di, ld) => (dynamic)new { Code = di.DeptCode, Name = di.DeptName, di.SpellCode, ld.Status })
                .ToArray();

            return data;
        }


        public object LimitPatUnChose(string drugCode)
        {
            var data = _client.Queryable<PatientInfo>()
                .LeftJoin<LimitDrug>((p, ld) => ld.DrugCode == drugCode && ld.Type == "2" && ld.Code == p.InpatientNo)
                .Where((p, ld) => p.Status == "1" && SqlFunc.EqualsNull(ld.DrugCode, null))
                .Select((p, ld) => (dynamic)new { Code = p.InpatientNo, Name = p.PatientName, p.DeptName, Status = "2" })//患者默认放开
                .ToArray();

            return data;
        }

        public object LimitPatChose(string drugCode)
        {
            var data = _client.Queryable<PatientInfo>()
                .InnerJoin<LimitDrug>((p, ld) => ld.DrugCode == drugCode && ld.Type == "2" && ld.Code == p.InpatientNo)
                .Where((p, ld) => p.Status == "1")
                .Select((p, ld) => (dynamic)new { Code = p.InpatientNo, Name = p.PatientName, p.DeptName, ld.Status })
                .ToArray();

            return data;
        }
    }
}
